#include <linux/input.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/time.h>
#include <signal.h> 
#include <time.h> 
#include <sys/time.h>
#include <sys/timerfd.h>
#include <unistd.h> 

#define _POSIX_C_SOURCE 199309 

#define KEY_EVENT_DEV_NAME "/dev/input/event0"
#define PRESSED  1
#define RELEASED 0
#define KEY1 108
#define KEY2 103


void timer_reboot(union sigval v) 
{
	printf("reboot ************************* 5S\n");
} 

void timer_power(union sigval v) 
{
	printf("power ************************* 5S\n");
} 

int sys_key_scan(void)
{
    int ret = -1;
    int key_fd = 0;
    struct input_event key_event = {0};
	timer_t timerid_reboot;
	timer_t timerid_power; 
	struct sigevent evp_reboot; 
	struct sigevent evp_power;
	static int flag = 0;

    
    key_fd = open(KEY_EVENT_DEV_NAME, O_RDONLY);
    if (key_fd <= 0) {
        printf("open event device error!\n");
        return ret;
    }

	memset(&evp_reboot, 0, sizeof(struct sigevent));
	memset(&evp_power, 0, sizeof(struct sigevent));
	evp_reboot.sigev_value.sival_int = 103;                //也是标识定时器的，回调函数可以获得 
    evp_reboot.sigev_notify = SIGEV_THREAD;                //线程通知的方式，派驻新线程 
    evp_reboot.sigev_notify_function = timer_reboot;       //线程函数地址 
	evp_power.sigev_value.sival_int = 108;                
    evp_power.sigev_notify = SIGEV_THREAD;                
    evp_power.sigev_notify_function = timer_power;       
 

    /* 第一次间隔it.it_value这么长,以后每次都是it.it_interval这么长,就是说it.it_value变0的时候会>装载it.it_interval的值 */
    struct itimerspec it; 
    it.it_interval.tv_sec = 1;  // 回调函数执行频率为1s运行1次
    it.it_interval.tv_nsec = 0; 
    it.it_value.tv_sec = 5;     // 倒计时5秒开始调用回调函数
    it.it_value.tv_nsec = 0; 

    while (1) {
        ret = lseek(key_fd, 0, SEEK_SET);
        ret = read(key_fd, &key_event, sizeof(key_event));
		//printf("whiel key %d %d sec = %d\n", key_event.code, (key_event.value), key_event.time.tv_sec);

        if (ret) {
			/* pressed */
			if (key_event.type == EV_KEY && (key_event.value == 1)) {
                //printf("key %d %s sec = %d\n", key_event.code, (key_event.value) ? "pressed": "released", key_event.time.tv_sec);

				if (key_event.code == KEY1) {	
					printf("key1 pressed\n");
					
					if (timer_create(CLOCK_REALTIME, &evp_reboot, &timerid_reboot) == -1) 
					{   
						perror("fail to timer_create"); 
						exit(-1); 
					}   

					if (timer_settime(timerid_reboot, 0, &it, NULL) == -1) {   
						perror("fail to timer_settime"); 
						exit(-1); 
					}
					
					if (!flag) {
						flag = 1;
						printf("on.\n");
					}
					else {
						flag = 0;
						printf("off.\n");
					}
				}
				if (key_event.code == KEY2) {
					printf("key2 pressed\n");

					if (timer_create(CLOCK_REALTIME, &evp_power, &timerid_power) == -1) 
					{   
						perror("fail to timer_create"); 
						exit(-1); 
					}   

					if (timer_settime(timerid_power, 0, &it, NULL) == -1) {   
						perror("fail to timer_settime"); 
						exit(-1); 
					}   
				}
            }
			/* released */
			else if (key_event.type == EV_KEY && (key_event.value == 0)) {
				if (key_event.code == KEY1) {	
					timer_delete(timerid_reboot);
					printf("key1 released\n");
				}
				if (key_event.code == KEY2) {	
					timer_delete(timerid_power);
					printf("key2 released\n");
				}
			}
        }
    }

    close(key_fd);

    return ret;
}

int main(int argc, char ** argv)
{
    printf("This is a key event test!\n");
    sys_key_scan();
}








/*
 * 释放后计时5S
 */
int sys_key_scan1(void)
{
    int ret = -1;
    int i = 0;
    int key_fd = 0;
	int key1_press = 0, key2_press = 0;
	int flag = 0;
    struct input_event key_event = {0};
	struct timespec key1_begin, key1_cur;
	struct timespec key2_begin, key2_cur;
	static time_t lasttime; 
	time_t nowtime; 
	unsigned long sec = 0;

    
    key_fd = open(KEY_EVENT_DEV_NAME, O_RDONLY);
    if (key_fd <= 0) {
        printf("open event device error!\n");
        return ret;
    }

    while (1) {
        ret = lseek(key_fd, 0, SEEK_SET);
        ret = read(key_fd, &key_event, sizeof(key_event));
		//printf("whiel key %d %d sec = %d\n", key_event.code, (key_event.value), key_event.time.tv_sec);

        if (ret) {
			/* pressed */
            //if (key_event.type == EV_KEY && (key_event.value == 0 || key_event.value == 1)) {
			if (key_event.type == EV_KEY && (key_event.value == 1)) {
                //printf("key %d %s sec = %d\n", key_event.code, (key_event.value) ? "pressed": "released", key_event.time.tv_sec);

                if (key_event.code == KEY_ESC)
                    break;

				if (key_event.code == KEY1) {	
					sec = key_event.time.tv_sec;
					//printf("******* sec = %ld\n", sec);
					printf("key pressed\n");
				}
				if (key_event.code == KEY2) {
					printf("key 2\n");
				}
            }
			/* released */
			else if (key_event.type == EV_KEY && (key_event.value == 0)) {
				if (key_event.code == KEY1) {	

					//printf("******* sec = %ld key_event.time.tv_sec = %d\n", sec, key_event.time.tv_sec);
					if (key_event.time.tv_sec - sec >= 5) {
						printf("key1 **************************************** 5S\n");
					}

					printf("key released\n");
				}
			}
        }

#if 0
		if (key_event.code == KEY1 && key_event.value == 2) {
			if (key1_press == 0) {
				clock_gettime(CLOCK_REALTIME, &key1_begin);
				key1_press = 1;
				printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
			}
			else {
				printf("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n");
				clock_gettime(CLOCK_REALTIME, &key1_cur);
				if (key1_cur.tv_sec - key1_begin.tv_sec >= 5) {
					key1_press = 0;
					printf("key1 **************************************** 5S\n");
				}
			}
		}
#endif
    }

    close(key_fd);

    return ret;
}
